package com.hollycrm.hollysqm.analyzer.util;

import com.hollycrm.hollysqm.analyzer.dic.Dictionary;
import com.hollycrm.hollysqm.analyzer.seg.impl.AnsjWordSegmenter;
import org.apache.commons.lang.StringUtils;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import static com.hollycrm.hollysqm.analyzer.util.Constant.defaultCharacterSet;
import static com.hollycrm.hollysqm.analyzer.util.Constant.silenceSplitMark;


/**
 * 分词器工具类
 * by zhaihw
 */
public class SegmenterUtil {
    private static String cnChars = "ａｂｃｄｅｆｇｈｉｊｋｌｍｎｏｐｑｒｓｔｕｖｗｘｙｚＡＢＣＤＥＦＧＨＩＪＫＬＭＮＯＰＱＲＳＴＵＶＷＸＹＺ０１２３４５６７８９　";

    private static String enChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ";

    /**
     * 切词，并进行去噪
     * @param src 原始词
     * @return 切分以后的词，以空格分开
     */
    public static String splitWithDeNoising(String src){
        src=replace(src);//简单去噪
        src=segTag(src);//切词
        src=deNoising(src);//去噪
        return src;
    }

    /**
     * 分词，无词性标注，不进行去噪
     * @param src 原始语句
     * @param minLength 返回单个词的最小长度
     * @return
     */
    public static String[] splitWithout(String src,int minLength){
        if(StringUtils.isEmpty(src))return null;
        String temp=AnsjWordSegmenter.getInstance().processWithoutNature(src);
        String[] words=temp.split(" ");
        List<String> dest=new ArrayList<>();
        for(String word:words){
            if(word.length()<minLength)continue;
            dest.add(word);
        }
        return dest.toArray(new String[]{});
    }

    /**
     * 返回切词以后的字符串
     * @param src 原始串
     * @return
     */
    public static String segTag(String src){
        return segTag(src,true);
    }

    /**
     * 切词
     * @param src 原始语句
     * @param isTag 是否标注词性
     * @return
     */
    public static String segTag(String src,boolean isTag){
        if(isTag)
            return AnsjWordSegmenter.getInstance().processWithNature(src);
        else
            return AnsjWordSegmenter.getInstance().processWithoutNature(src);
    }

    /**
     * 去除噪声词，保留指定词性的词
     * @param src 原始词组，词之间以空格分开，词与词性以/分割
     * @param speeches 保留的词性集合
     * @param isSaveSpeech 是否保留词性
     * @return
     */
    public static String deNoising(String src,Set<String> speeches,boolean isSaveSpeech){
        if(StringUtils.isEmpty(src))
            return src;
        StringBuilder buffer=new StringBuilder();
        String[] wordParts=src.split(" ");//词/词性 格式的数组
        for(String wp:wordParts){
            String[] wps=wp.split("/");//词 与 词性 的数组
            if(wps.length!=2)continue;//无法定位词性 则忽略
            if(wps[0].length()<=1) continue;//词长小于等于1 则忽略
            if(Dictionary.getStopWords().contains(wps[0]))continue;//包含于噪声词典中，则忽略
            if(speeches!=null && !speeches.contains(wps[1]))continue;//如果不属于指定词性的词，则忽略
            if(isSaveSpeech)
                buffer.append(wp).append(" ");
            else
                buffer.append(wps[0]).append(" ");
        }
        return buffer.toString();
    }
    /**
     * 去噪,不保留词性
     * @param src 原始词 词与词之间空格隔开，词与词性之间/隔开
     * @return 去噪之后的词，以空格分开
     */
    public static String deNoising(String src){
        return deNoising(src,Dictionary.getRemainWords(),false);
    }

    /**
     * 去噪 并保留词性
     * @param src 原始串
     * @return 词与词之间空格 词与词性之间/分割
     */
    public static String deNoisingWithSpeech(String src){
        if(StringUtils.isEmpty(src))return null;
        return deNoising(src,Dictionary.getRemainWords(),true);
    }
    /**
     * 将中文全角字符转换为引文字符
     * @param str
     * @return
     */
    public static String CnChar2EnChar(String str){
        if(StringUtils.isEmpty(str))
            return str;
        StringBuilder buffer=new StringBuilder();
        char[] cArrays=str.toCharArray();
        for(char c:cArrays){
            int idx=cnChars.indexOf(c);
            if(idx>=0)
                buffer.append(enChars.substring(idx,idx+1));
            else
                buffer.append(c);
        }
        return buffer.toString();
    }

//    /**
//     * 学习新词
//     * @param sentence 句子
//     * @return 新词
//     * @throws Exception
//     */
//    public static String learnNewWord(String sentence)throws Exception{
//        return AnsjWordSegmenter.getInstance().findNewWord(sentence);
//    }

//    /**
//     * 学习新词
//     * @param sentence 句子
//     * @return 新词
//     * @throws Exception
//     */
//    public static String learnNewWord(List<String> sentence)throws Exception{
//
//        return SegmentFactory.defaultSegment().findNewWord(sentence.toArray(new String[sentence.size()]));
//    }
//
//    /**
//     * 学习新词
//     * @param path 文件路径
//     * @return 新词
//     * @throws Exception
//     */
//    public static String learnNewWordByFile(String path)throws Exception{
//        return SegmentFactory.defaultSegment().findNewWordByFile(path);
//    }
    /**
     * 加载用户词典
     * @param nature 词性
     * @param words 词语
     */
    public static void loadUserWord(String nature,String ... words) {
        AnsjWordSegmenter.getInstance().loadUserWord(nature,words);
    }

    /**
     * 加载停用词
     * @param stopWords   停用词
     * @return 加载成功数量
     */
    public static void loadStopWord(String ...stopWords) {
        AnsjWordSegmenter.getInstance().loadStopWord(stopWords);
    }
    /**
     * 简单去除噪声词
     * @param nativeStr
     * @return
     */
    public static String replace(String nativeStr) {
        nativeStr = CnChar2EnChar(nativeStr);
        nativeStr = nativeStr.toUpperCase();
        nativeStr = nativeStr.replaceAll("喂", "");
        nativeStr = nativeStr.replaceAll("呀", "");
        nativeStr = nativeStr.replaceAll("哎", "");
        nativeStr = nativeStr.replaceAll("嗯", "");
        nativeStr = nativeStr.replaceAll("哦", "");
        nativeStr = nativeStr.replaceAll("吗", "");
        nativeStr = nativeStr.replaceAll("呃", "");
        nativeStr = nativeStr.replaceAll("呢", "");
        nativeStr = nativeStr.replaceAll("啊", "");
        nativeStr = nativeStr.replaceAll("嘛", "");
        nativeStr = nativeStr.replaceAll("吧", "");
        nativeStr = nativeStr.replaceAll("啊", "");
        nativeStr = nativeStr.replaceAll("的话", "");
        nativeStr = nativeStr.replaceAll("是这样的", "");
        nativeStr = nativeStr.replaceAll("是的", "");
        nativeStr = nativeStr.replaceAll("请问什么可以帮您", "");
        nativeStr = nativeStr.replaceAll("请问有什么可以帮您", "");
        nativeStr = nativeStr.replaceAll("感谢您的来电", "");
        nativeStr = nativeStr.replaceAll("好的", "");
        nativeStr = nativeStr.replaceAll("您好", "");
        nativeStr = nativeStr.replaceAll("你好", "");
        nativeStr = nativeStr.replaceAll("稍等一下", "");
        nativeStr = nativeStr.replaceAll("感谢您的耐心等待", "");
        nativeStr = nativeStr.replaceAll("祝您节日愉快", "");
        nativeStr = nativeStr.replaceAll("再见", "");
        nativeStr = nativeStr.replaceAll("麻烦您对我的服务进行", "");
        nativeStr = nativeStr.replaceAll("祝您生活愉快", "");
        nativeStr = nativeStr.replaceAll("您的电话无声请您重新拨打", "");
        nativeStr = nativeStr.replaceAll("谢谢", "");
        nativeStr = nativeStr.replaceAll("先生", "");
        nativeStr = nativeStr.replaceAll("女士", "");
        nativeStr = nativeStr.replaceAll("小姐", "");
        nativeStr = nativeStr.replaceAll("#", "");

        nativeStr = nativeStr.replaceAll("两G", "2G");
        nativeStr = nativeStr.replaceAll("三G", "3G");
        nativeStr = nativeStr.replaceAll("四G", "4G");
        nativeStr = nativeStr.replace("IPHONE 5", "IPHONE5");
        nativeStr = nativeStr.replace("IPHONE 4", "IPHONE4");
        nativeStr = nativeStr.replace("IPHONE 4S", "IPHONE4S");
        return nativeStr;
    }


    /**
     * 分词
     * @param originalFile 原始文件
     * @param splitFile 分词文件
     * @throws IOException 异常
     */
    public static void split(String originalFile, String splitFile) throws IOException{
        BufferedReader br = null;
        BufferedWriter bw = null;
        try {
            br = new BufferedReader(new InputStreamReader(
                    new FileInputStream(new File(originalFile)), defaultCharacterSet));

            StringBuilder buf = new StringBuilder();
            String line;
            while ((line = br.readLine()) != null) {
                String[] idWords = line.split(silenceSplitMark);
                if (idWords.length == 2) {
                    String splitWord = idWords[1];
                    if (StringUtils.isNotEmpty(splitWord)) {
                        splitWord = splitWithDeNoising(splitWord);
                        if (StringUtils.isNotEmpty(splitWord))
                            buf.append(idWords[0]).append(silenceSplitMark).append(splitWord).append("\r\n");
                    }
                }
            }
            bw = new BufferedWriter(new OutputStreamWriter(
                    new FileOutputStream(new File(splitFile)), defaultCharacterSet));
            bw.write(buf.toString());
            bw.flush();
        } catch (IOException e) {
            throw new IOException();
        } finally {
            try {
                if (br != null) br.close();
                if (bw != null) bw.close();
            } catch (IOException e) {}
        }


    }
}
